-
Notifications
You must be signed in to change notification settings - Fork 462
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add WithPgWeb
#5098
Add WithPgWeb
#5098
Conversation
playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/Program.cs
Outdated
Show resolved
Hide resolved
@Alirexaa this is looking pretty good. A few minor things. We'll need a docs issue/PR filed for this as well (probably just updating the existing doc page for Postgres). |
@mitchdenny besides these things, this PR needs more work to do, right now bookmarks populate in pgweb but when selecting one of those to connect, connection refuse occur. |
To pass all tests we need to import |
@eerhardt could you please import |
@@ -11,4 +11,7 @@ internal static class PostgresContainerImageTags | |||
public const string PgAdminRegistry = "docker.io"; | |||
public const string PgAdminImage = "dpage/pgadmin4"; | |||
public const string PgAdminTag = "8.8"; | |||
public const string PgWebRegistry = "docker.io"; | |||
public const string PgWebImage = "sosedoff/pgweb"; | |||
public const string PgWebTag = "latest"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've been not using latest
tags as much as possible due to non-determinism. See examples:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now we use the 0.15.0
tag,Could you please import docker.io/sosedoff/pgweb:0.15.0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eerhardt already did it!
{ | ||
var adminResource = appModel.Resources.OfType<PgWebContainerResource>().Single(); | ||
var serverFileMount = adminResource.Annotations.OfType<ContainerMountAnnotation>().Single(v => v.Target == "/.pgweb/bookmarks"); | ||
var postgresInstances = appModel.Resources.OfType<PostgresDatabaseResource>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to do this for all PostgresDatabaseResource instances? Or just the ones that had .WithPgWeb()
called on them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to introduce a new annotation to make a relation between PgWebContainerResource
and PostgresDatabaseResource
or maybe something like this
public sealed class PgWebContainerResource(string name,PostgresDatabaseResource postgresDatabaseResource) : ContainerResource(name)
{
public PostgresDatabaseResource PostgresDatabaseResource { get; } = postgresDatabaseResource;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eerhardt, what about this?
We have same behavior for pgadmin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess if the behavior is the same as pgadmin, then I'm fine. If we feel we should have a different behavior for both - log an issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have an open issue for that. see #2060.
builder.ApplicationBuilder.Services.TryAddLifecycleHook<PgWebConfigWriterHook>(); | ||
|
||
containerName ??= $"{builder.Resource.Name}-pgweb"; | ||
var dir = Directory.CreateTempSubdirectory().FullName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this directory get cleaned up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have a hook or event when a resource stopped/finished?
I think we should add one API for that in IDistributedApplicationLifecycleHook
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually a problem right now. @karolz-ms interested in your thoughts here. We sometimes drop temporary files in disk and I'd like to be able to try and ensure that they are cleaned up. We can probably have some kind of temporary file register that goes and does clean up but its highly likely that some of those files/directories are going to be locked because things like containers are spinning down.
This might be one of those things that DCP could help with?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think DCP would be a good place for logic that deals with "cleanup" tasks like removing temporary log files.
There are probably many ways to do this, but the simplest one that will work today, is to put them inside the DCP session folder (which the app host runtime knows about). That folder is automatically deleted when DCP is shutting down. Just make sure the name is reasonably unique when creating the file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(we might be missing an API for the extensions that will tell them what the "temporary folder for the current application run" is)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do that too. Feel free to open an issue and we can add it to our backlog for DCP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is our approach for cleanup temp files for this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mitchdenny - would this be a good usage of the new Eventing API? We could have an event that fires when the resource is shut down.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is our approach for cleanup temp files for this PR?
Since we already have the same issue with pgadmin:
aspire/src/Aspire.Hosting.PostgreSQL/PostgresBuilderExtensions.cs
Lines 101 to 111 in 4b4ebce
.WithBindMount(Path.GetTempFileName(), "/pgadmin4/servers.json") | |
.ExcludeFromManifest(); | |
builder.ApplicationBuilder.Eventing.Subscribe<AfterEndpointsAllocatedEvent>((e, ct) => | |
{ | |
var serverFileMount = pgAdminContainer.Annotations.OfType<ContainerMountAnnotation>().Single(v => v.Target == "/pgadmin4/servers.json"); | |
var postgresInstances = builder.ApplicationBuilder.Resources.OfType<PostgresServerResource>(); | |
var serverFileBuilder = new StringBuilder(); | |
using var stream = new FileStream(serverFileMount.Source!, FileMode.Create); |
I'd be fine with continuing here to just create temp files and leave them, for now, until we get the clean up capability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes ... although it wouldn't be 100%. If someone kills the process via the debugger (most common scenario) I don't think we guarantee that this is run. But better than nothing I guess.
playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/Program.cs
Outdated
Show resolved
Hide resolved
{ | ||
var adminResource = appModel.Resources.OfType<PgWebContainerResource>().Single(); | ||
var serverFileMount = adminResource.Annotations.OfType<ContainerMountAnnotation>().Single(v => v.Target == "/.pgweb/bookmarks"); | ||
var postgresInstances = appModel.Resources.OfType<PostgresDatabaseResource>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess if the behavior is the same as pgadmin, then I'm fine. If we feel we should have a different behavior for both - log an issue.
Can you please add some information in PR description, maybe even just links to pgweb? |
I've pushed it to the netaspireci.azurecr.io registry. However, I don't believe the test will pass because the CI machines don't have Docker Desktop installed, which means there isn't network communication between the containers. |
What can I do for that? |
For now we've been disabling the test in CI until the problem can be resolved. |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for this contribution!
In this PR, we add pgweb (https://github.com/sosedoff/pgweb) a web-based admin dashboard for PostgreSQL.
using
WithPgWeb
, We collect all registeredPostgresDatabaseResource
instances and create a configuration file per instance, then bind the location of these files to the pgweb containerbookmark
directory. for more information about pgweb bookmark you can see https://github.com/sosedoff/pgweb/wiki/Server-Connection-Bookmarks.We used the Eventing API and subscribed
AfterEndpointsAllocatedEvent
to create configuration files.We used pgweb
connect
API for functional testing to ensure pgweb is configured correctly.close: #3081
Microsoft Reviewers: Open in CodeFlow